package com.foreveross.proxyip.core.http.ipdoload.website;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.log4j.Logger;

import com.dayatang.domain.InstanceFactory;
import com.foreveross.proxyip.core.BaseCode;
import com.foreveross.proxyip.core.pools.PoolsManager;
import com.foreveross.proxyip.core.redis.IpStoreMap;
import com.foreveross.proxyip.core.redis.PiRedisExecption;
import com.foreveross.proxyip.entity.IpStoreEntity;
import com.foreveross.proxyip.entity.IpWebsiteEntity;
import com.foreveross.proxyip.entity.ProxyIpBean;
import com.foreveross.proxyip.infra.base.ddd.repository.IBaseRepository;
import com.foreveross.proxyip.infra.cache.BufferCacheManager;
import com.foreveross.proxyip.infra.cache.BufferInstance;
import com.foreveross.proxyip.infra.cache.Operations;
import com.foreveross.proxyip.infra.conf.PropertyUtils;
import com.foreveross.proxyip.infra.conf.system.DefaultPropertiesLoader;
import com.foreveross.proxyip.infra.db.mongo.IMongoRepository;
import com.foreveross.proxyip.infra.db.mongo.MongoRepositoryImpl;
import com.foreveross.proxyip.util.IpWebiteUtil;
import com.foreveross.proxyip.util.RegUtil;

/**
 * 并行解释行记录
 * 
 * @author lyq
 * 
 */
@SuppressWarnings("rawtypes")
public class ExplainIpsCall implements Callable {
	@SuppressWarnings("unused")
	private static final Logger log = Logger.getLogger(ExplainIpsCall.class);
	List ips = null;
	IpWebsiteEntity website = null;
	Map<String, ProxyIpBean> proxyIpMap = null;
	IBaseRepository baseRepository = null;
	private PoolsManager poolsManager = null;

	private IMongoRepository mongoRepository;

	private Integer cacheEntitycount = null;

	public ExplainIpsCall(List ips, IpWebsiteEntity website,
			Map<String, ProxyIpBean> proxyIpMap, IBaseRepository baseRepository) {
		this.ips = ips;
		this.website = website;
		this.proxyIpMap = proxyIpMap;
		this.baseRepository = baseRepository;
		mongoRepository = new MongoRepositoryImpl("proxyip");
	}

	@Override
	public Object call() throws Exception {
		List<IpStoreEntity> mongoList = new ArrayList<IpStoreEntity>();

		for (int j = 0; j < ips.size(); j++) {
			if (RegUtil.getIpPort(ips.get(j).toString()) != null) {
				ProxyIpBean bean = new ProxyIpBean();

				// list.add(bean);
				// this.setIpStoreEntity(bean, ips[j].toString().trim());
				IpWebiteUtil.explainRow(bean, website, ips.get(j).toString().trim());
				IpStoreEntity oldIpStore = this.getIpStoreEntityByIp(bean.getIp(), bean.getPort());

				bean.setSource(website.getName());
				bean.setCreateTime(new Date());
				bean.setLastTime(new Date());
				bean.setState(0);// /还没被使用
				// tempList.add(bean.toIpStoreTmpEntity());
				if (oldIpStore == null) {

					// this.creatNew(bean);
					// baseRepository.transSave(bean.toIpStoreEntity());
					BufferInstance bufferinstance = new BufferInstance(bean.toIpStoreEntity(), Operations.CREATE);
					if (cacheEntitycount == null) {
						try {
							cacheEntitycount = Integer.parseInt(BaseCode.getValue("TASKQUEUELOG_CACHEENTITYCOUNT"));
						} catch (NumberFormatException e) {
							e.printStackTrace();
						} catch (PiRedisExecption e) {
							e.printStackTrace();
						}
					}
					BufferCacheManager.getInstance(cacheEntitycount).excure(bufferinstance, "ipStore");

					// BufferInstance bufferinstance = new
					// BufferInstance(bean.toIpStoreEntity(),
					// Operations.CREATE);
					// BufferCacheManager.getInstance().excure(bufferinstance,"ipStore");
				} else if (oldIpStore.getCreateTime().getTime() < System.currentTimeMillis() - 60 * 30 * 1000) {
					// 如果数据库已存在该ip且上次存在于程序的时间已经超过半个钟
					// IpStoreEntity newStore =
					// (IpStoreEntity)BeanUtils.cloneBean(oldIpStore);//去缓存
					// newStore.setLastTime(new Date());
					// BufferInstance bufferinstance = new
					// BufferInstance(newStore, Operations.UPDATE);
					// BufferCacheManager.getInstance().excure(bufferinstance,"ipStore");
				}

				// markMongo
				mongoList.add(bean.toIpStoreEntity());
				if (IpStoreMap.getIntance().containsKey(bean.getCompletionIP())
						|| getPoolManager().getPublicPool().contains(
								bean.getCompletionIP())
						|| proxyIpMap.containsKey(bean.getCompletionIP())) {
					continue;
				} else {
					proxyIpMap.put(bean.getCompletionIP(), bean);
				}
			}
		}
		
		// 批量保存
		if (PropertyUtils.getBooleanProperty("proxyip.isPersistentToMongo", DefaultPropertiesLoader.CONFIG_FILE)) {
			mongoRepository.save(mongoList);
		}
		
		return null;
	}

	//
	// /**
	// * 解释行记录
	// * @param ipStoreEntity
	// * @param website
	// * @param httpStr
	// * @throws InvocationTargetException
	// * @throws IllegalAccessException
	// */
	// private void explainRow(ProxyIpBean proxyIp,IpWebsiteEntity
	// website,String httpStr) {
	// try{
	// // Matcher matcher = website.getRowPattern().matcher(httpStr);
	// // StringUtils.su
	// // while(matcher.find()){
	// List<String> positions = website.getIpRowPositions();
	// List <String> tempPositions = new ArrayList<String>(positions);
	// for(int i=1;i<positions.size();i++){
	// if(httpStr.indexOf(positions.get(i).charAt(0))==-1){
	// tempPositions.remove(i);
	// }
	// }
	// for(int j=0;j<tempPositions.size();j++){
	// int start = 0;
	// int end = 0;
	// String name = "";
	// if(j==0){
	// end = httpStr.indexOf(tempPositions.get(j+1).charAt(0));
	// name = tempPositions.get(j);
	// }else if(j==tempPositions.size()-1){
	// start = httpStr.indexOf(tempPositions.get(j).charAt(0))+1;
	// end = httpStr.length();
	// name = StringUtils.substring(tempPositions.get(j), 1,
	// tempPositions.get(j).length());
	// }else{
	// start = httpStr.indexOf(tempPositions.get(j).charAt(0))+1;
	// end = httpStr.indexOf(tempPositions.get(j+1).charAt(0));
	// name = StringUtils.substring(tempPositions.get(j), 1,
	// tempPositions.get(j).length());
	// }
	// String value = StringUtils.substring(httpStr, start, end);
	// if(StringUtils.isNotBlank(name)){
	// BeanUtils.setProperty(proxyIp, name, value);
	// }
	// }
	//
	// }catch(Exception e){
	// log.error("解释页面结果记录失败;"+httpStr, e);
	// }
	// }

	private IpStoreEntity getIpStoreEntityByIp(String ip, Integer port) {
		Object[] params = { ip , port};
		List<IpStoreEntity> list = this.baseRepository.queryResult(
				"from IpStoreEntity t where t.ip=? and t.port = ?", params);
		if (list == null || list.size() == 0) {
			return null;
		}
		return list.get(0);
	}

	private PoolsManager getPoolManager() {
		if (poolsManager == null) {
			poolsManager = InstanceFactory.getInstance(PoolsManager.class);
		}
		return poolsManager;
	}

}